home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / co.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  6KB  |  248 lines

  1. /* co - check out            Author: Peter S. Housel 12/24/87 */
  2.  
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <string.h>
  6. #include <pwd.h>
  7. #include <stdio.h>
  8.  
  9. #define SUFFIX        ",S"    /* svc indicator */
  10. #define SVCDIR        "SVC"    /* svc postfix indicator */
  11.  
  12. #define LINELEN        256    /* maximum line length */
  13.  
  14. #ifdef MAXPATHLEN
  15. #define PATHLEN MAXPATHLEN
  16. #else
  17. #define PATHLEN 128        /* buffer length for filenames */
  18. #endif
  19.  
  20. char file[PATHLEN];        /* file to be checked in */
  21. char svc[PATHLEN];        /* filename for svc file */
  22. char newsvc[PATHLEN];        /* new copy of SVC file */
  23. char line[LINELEN];        /* temporary line buffer */
  24. char *p;            /* scratch character pointer */
  25.  
  26. FILE *svcfp;            /* svc file */
  27. int rev;            /* old revision number */
  28. int lastrev, lockrev;        /* latest file revision, lock into */
  29. int status;            /* wait() buffer */
  30. int lock;            /* lock the SVC file */
  31. struct stat stb;        /* stat() buffer */
  32. char *base;            /* basename of file */
  33.  
  34. char difftemp[PATHLEN];        /* extract() fix/patch input */
  35.  
  36. extern char *mktemp();
  37. extern struct passwd *getpwuid();
  38.  
  39. char *whoami(), *basename();
  40.  
  41. main(argc, argv)
  42. int argc;
  43. char **argv;
  44. {
  45. #ifdef perprintf
  46.   char errbuf[BUFSIZ];
  47.   setbuf(stderr, errbuf);
  48.   perprintf(stderr);
  49. #endif
  50.  
  51.   while (++argv, --argc) {
  52.     if ('-' == (*argv)[0]) {
  53.         if ('r' == (*argv)[1]) {
  54.             --argc;
  55.             rev = atoi(*++argv);
  56.             if (rev < 1) {
  57.                 fprintf(stderr, "Illegal revision number\n");
  58.                 exit(1);
  59.             }
  60.         } else if ('l' == (*argv)[1])
  61.             ++lock;
  62.         else {
  63.             fprintf(stderr, "co: illegal option -%c\n", (*argv)[1]);
  64.             exit(1);
  65.         }
  66.     } else
  67.         break;
  68.   }
  69.  
  70.   if (1 != argc) {
  71.     fprintf(stderr, "co: bad number of files arguments\n");
  72.     exit(1);
  73.   }
  74.   fname(*argv, file);
  75.   svcname(file, svc);
  76.  
  77.   fprintf(stderr, "%s -> %s\n", svc, base = basename(file));
  78.  
  79.   if ((FILE *) NULL == (svcfp = fopen(svc, "r"))) {
  80.     perror("co: can't read SVC file");
  81.     exit(1);
  82.   }
  83.   if (1 != fscanf(svcfp, "# %d", &lastrev) || lastrev < 1) {
  84.     fprintf(stderr, "co: illegal SVC file format\n");
  85.     exit(1);
  86.   }
  87.   fclose(svcfp);
  88.  
  89.   if (stat(base, &stb) >= 0 && (stb.st_mode & 0222)) {
  90.     fprintf(stderr, "Writable %s exists - overwrite (n/y)? ", base);
  91.     if (!getyn()) {
  92.         fprintf(stderr, "Checkout aborted\n");
  93.         exit(1);
  94.     }
  95.   }
  96.   if (strlen(base)) unlink(base);
  97.   if (0 == rev) rev = lastrev;
  98.   fprintf(stderr, "Checking out revision %d", rev);
  99.   extract(svc, base, rev);
  100.  
  101.   if (lock) {
  102.     lockrev = lastrev + 1;
  103.     fprintf(stderr, "; Locking into revision %d\n", lockrev);
  104.     if (stat(svc, &stb) < 0 || chmod(svc, stb.st_mode | 0200) < 0)
  105.         perror("co: can't chmod SVC file");
  106.  
  107.     if (stat(base, &stb) < 0 || chmod(base, stb.st_mode | 0200) < 0)
  108.         perror("co: can't chmod source file");
  109.  
  110.     if ((FILE *) NULL == (svcfp = fopen(svc, "a"))
  111.         || (fprintf(svcfp, "#***SVCLOCK*** %s %d\n", whoami(), lockrev), ferror(svcfp))) {
  112.         fprintf(stderr, "co: can't lock %s\n", svc);
  113.         exit(1);
  114.     }
  115.     if (stat(svc, &stb) < 0 || chmod(svc, stb.st_mode & 0555))
  116.         perror("co: can't chmod SVC file");
  117.   } else {
  118.     putchar('\n');
  119.     if (stat(base, &stb) < 0 || chmod(base, stb.st_mode & 0555))
  120.         perror("co: can't chmod source file");
  121.   }
  122.  
  123.   exit(0);
  124. }
  125.  
  126.  
  127. fname(src, dst)
  128. char *src, *dst;
  129. {
  130.   char *p;
  131.   strcpy(dst, src);
  132.   p = &dst[strlen(src) - strlen(SUFFIX)];
  133.   if (!strcmp(p, SUFFIX)) *p = '\0';
  134. }
  135.  
  136. svcname(src, dst)
  137. char *src, *dst;
  138. {
  139.   char *p;
  140.  
  141.   strcpy(dst, src);
  142.   strcat(dst, SUFFIX);
  143.  
  144.   if (0 != access(dst, 4)) {
  145.     char dirname[PATHLEN];
  146.     if ( (char *) NULL != (p = strrchr(src, '/')))
  147.         strncpy(dirname, src, (int)(p - src) + 1);
  148.     else
  149.         dirname[0] = '\0';
  150.     strcat(dirname, SVCDIR);
  151.  
  152.     if (0 == access(dirname, 1)) {
  153.         strcpy(dst, dirname);
  154.         if ((char *) NULL == p) {
  155.             strcat(dst, "/");
  156.             strcat(dst, src);
  157.         } else
  158.             strcat(dst, p);
  159.         strcat(dst, SUFFIX);
  160.     }
  161.   }
  162. }
  163.  
  164. extract(script, out, rev)
  165. char *script, *out;
  166. int rev;
  167. {
  168.   FILE *outfp;
  169.   int testrev;
  170.   char buf[80];
  171.  
  172.   sprintf(difftemp, "Fix.%s", out);
  173.  
  174.   svcfp = fopen(script, "r");
  175.   fgets(line, LINELEN, svcfp);    /* skip '# rev' line */
  176.   fgets(line, LINELEN, svcfp);    /* skip 'cat <***MAIN-eof***' line */
  177.  
  178.   if ((FILE *) NULL == (outfp = fopen(out, "w"))) {
  179.     perror("co: can't create output file");
  180.     return;
  181.   }
  182.   while ((char *) NULL != fgets(line, LINELEN, svcfp) &&
  183.       strcmp(line, "***MAIN-eof***\n"))
  184.     fputs(line, outfp);
  185.  
  186.   fclose(outfp);
  187.  
  188.   while ((char *) NULL != fgets(line, LINELEN, svcfp)) {
  189.     if (!strncmp(line, "if ", 3)) {
  190.         sscanf(line, "if test $2 -ge %d", &testrev);
  191.         if (rev >= testrev) {
  192.             unlink(difftemp);
  193.             return;
  194.         }
  195.         if ((FILE *) NULL == (outfp = fopen(difftemp, "w"))) {
  196.             perror("co: can't create output file");
  197.             return;
  198.         }
  199.         sprintf(buf, "***%d-eof***\n", testrev);
  200.         while ((char *) NULL != fgets(line, LINELEN, svcfp) &&
  201.                             strcmp(line, buf))
  202.             fputs(line, outfp);
  203.         fclose(outfp);
  204.     } else if (!strncmp(line, "mv ", 3)) {
  205.         sprintf(buf, "mv Fix.%s %s", out, out);
  206.         system(buf);
  207.     } else if (!strncmp(line, "fix ", 4)) {
  208.         sprintf(buf, "fix %s Fix.%s > New.%s; mv New.%s %s", out, out, out, out, out);
  209.         system(buf);
  210.     } else if (!strncmp(line, "patch ", 6)) {
  211.         sprintf(buf, "patch -n -s %s < Fix.%s; rm -f %s.orig", out, out, out);
  212.         system(buf);
  213.     } else {        /* ignore */
  214.     }
  215.   }
  216.  
  217.   unlink(difftemp);
  218.   return;
  219. }
  220.  
  221. char *basename(name)
  222. char *name;
  223. {
  224.   char *p;
  225.  
  226.   if ((char *) NULL == (p = strrchr(name, '/')))
  227.     return name;
  228.   else
  229.     return p + 1;
  230. }
  231.  
  232. char *whoami()
  233. {
  234.   struct passwd *pw;
  235.  
  236.   if ((struct passwd *) NULL != (pw = getpwuid(getuid())))
  237.     return pw->pw_name;
  238.   else
  239.     return "nobody";
  240. }
  241.  
  242. int getyn()
  243. {
  244.   char ans[10];
  245.  
  246.   return((char *) NULL != fgets(ans, 10, stdin)) && ('y' == ans[0] || 'Y' == ans[0]);
  247. }
  248.